home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume23 / pty / part03 < prev    next >
Encoding:
Internet Message Format  |  1991-01-08  |  54.8 KB

  1. Path: j.cc.purdue.edu!mentor.cc.purdue.edu!purdue!bu.edu!rpi!zaphod.mps.ohio-state.edu!swrinde!cs.utexas.edu!uunet!papaya.bbn.com!rsalz
  2. From: rsalz@bbn.com (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v23i033:  Run a program under a pty session, Part03/06
  5. Message-ID: <2883@litchi.bbn.com>
  6. Date: 10 Oct 90 14:16:40 GMT
  7. Organization: BBN Systems and Technologies, Cambridge MA
  8. Lines: 2170
  9. Approved: rsalz@uunet.UU.NET
  10.  
  11. Submitted-by: Dan Bernstein <brnstnd@kramden.acf.nyu.edu>
  12. Posting-number: Volume 23, Issue 33
  13. Archive-name: pty/part03
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  20. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  21. # Contents:  config.h logs.c pty.1 sigler.c sock.c tty.c util/Makefile
  22. # Wrapped by rsalz@litchi.bbn.com on Wed Oct 10 10:11:38 1990
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 3 (of 6)."'
  26. if test -f 'config.h' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'config.h'\"
  28. else
  29.   echo shar: Extracting \"'config.h'\" \(9610 characters\)
  30.   sed "s/^X//" >'config.h' <<'END_OF_FILE'
  31. X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
  32. X
  33. X#ifndef PTY_CONFIG_H
  34. X#define PTY_CONFIG_H
  35. X
  36. X/* It is recommended that you make local changes in the Makefile, */
  37. X/* except for feature control, which is best done here. */
  38. X
  39. X/* Section 1: Feature control. */
  40. X/* Section 2: Pseudo-terminal pathnames. */
  41. X/* Section 3: Logging. */
  42. X/* Section 4: Protection. */
  43. X/* Section 5: Other. */
  44. X/* Section 6: Sanity checks. */
  45. X
  46. X/* Each section starts with the necessary defines and finishes with */
  47. X/* an explanation. */
  48. X
  49. X
  50. X/* Section 1: Feature control. */
  51. X
  52. X/*#define MUST_UTMP  /* force utmp logging */
  53. X/*#define NO_UTMP  /* prohibit utmp logging */
  54. X/*#define MUST_WTMP  /* force utmp logging */
  55. X/*#define NO_WTMP  /* prohibit wtmp logging */
  56. X/*#define MUST_SESSION  /* force disconnectable sessions (what for?) */
  57. X/*#define NO_SESSION  /* prohibit disconnectable sessions */
  58. X/*#define MUST_CHOWN  /* force changing pty owner */
  59. X/*#define NO_CHOWN  /* prohibit changing pty owner */
  60. X/*#define NO_FDPASSING  /* prohibit file descriptor passing */
  61. X/*#define NO_UNIXSOCKS  /* prohibit use of UNIX-domain sockets */
  62. X#define TTY_WINDOWS  /* have winsize, WINCH, etc. in tty (4.3) */
  63. X/*#define TTY_AUXCHARS  /* have systat, e.g. with ^T, in tty */
  64. X#define DESPERATE_ALARMS  /* if NDELAY may not be enough */
  65. X#define DONT_NDELAY  /* might as well, with DESPERATE_ALARMS */
  66. X#define SIGINTERRUPT  /* if you have siginterrupt() (4.3) */
  67. X#define USLEEP  /* if you have usleep() */
  68. X
  69. X/* These are mostly self-explanatory. If your system doesn't support */
  70. X/* some feature, you should prohibit it by defining NO_WHATEVER. */
  71. X
  72. X/* Any BSD 4.2 or 4.3 system should have UNIXSOCKS and FDPASSING. Look */
  73. X/* for /sys/h/un.h to see if you have UNIX-domain sockets. Look for */
  74. X/* msg_accrights in the man page for recvmsg() to see if you have */
  75. X/* file desriptor passing. (Sometimes fd passing is available but buggy, */
  76. X/* as it's a relatively new, powerful, and rarely exploited feature. In */
  77. X/* this case you should define NO_FDPASSING.) In the current version, */
  78. X/* NO_UNIXSOCKS implies NO_FDPASSING and NO_SESSION; see Section 6. */
  79. X
  80. X/* For TTY_WINDOWS, look for struct winsize in /usr/include/sgtty.h. */
  81. X/* For TTY_AUXCHARS, look for struct auxchars in the same place. */
  82. X/* All BSD 4.3 systems should have winsize; auxchars isn't so common. */
  83. X
  84. X/* Opening the slave side of a pty without a master should hang the */
  85. X/* process. Normally, opening with NDELAY gets around this effect; */
  86. X/* opening the slave side first is necessary for some security checks. */
  87. X/* On some systems, however, NDELAY doesn't do its job; you must */
  88. X/* define DESPERATE_ALARMS to forcibly interrupt each open(). There */
  89. X/* shouldn't be any problem in leaving this (and DONT_NDELAY) defined */
  90. X/* anyway. (On a few systems, you must have DONT_NDELAY for -xn.) */
  91. X
  92. X/* Define SIGINTERRUPT if you have siginterrupt() (i.e., if you're */
  93. X/* running BSD 4.3). Without this call, there's no correct way to do */
  94. X/* per-process nonblocking I/O, and pty may block when it shouldn't */
  95. X/* (namely, when it has N bytes to write to the output, the output is */
  96. X/* a blocking pipe with M bytes of space, and N > M > 0). If you define */
  97. X/* SIGINTERRUPT, pty will take some extra effort to never, ever, ever */
  98. X/* block when it doesn't have to. (See OUTBUFSIZE, below.) */
  99. X
  100. X/* Define USLEEP if you have usleep(). */
  101. X
  102. X
  103. X/* Section 2: Pathnames. */
  104. X
  105. X#ifndef PTYDIR
  106. X#define PTYDIR "/usr/etc/pty"
  107. X#endif
  108. X#ifndef DEVMTY
  109. X#define DEVMTY "/dev/pty  "
  110. X#endif
  111. X#ifndef DEVSTY
  112. X#define DEVSTY "/dev/tty  "
  113. X#endif
  114. X#ifndef PTY1
  115. X#define PTY1 "pqrstuvwxyzabcdefghijklmno"
  116. X#endif
  117. X#ifndef PTY2
  118. X#define PTY2 "0123456789abcdef"
  119. X#endif
  120. X#ifndef TTYNAMELEN
  121. X#define TTYNAMELEN 30
  122. X#endif
  123. X
  124. X/* PTYDIR is where pty sessions store their information. You should */
  125. X/* create it mode 700, owner pty, group irrelevant. You must define */
  126. X/* PTYDIR as something even if you don't allow sessions. If you don't */
  127. X/* set up PTYDIR at all but you do allow sessions, pty will switch */
  128. X/* out of setuid after grabbing a pty, then set up session information */
  129. X/* in the user's home directory. This isn't totally secure but it's */
  130. X/* at least partially workable. */
  131. X
  132. X/* DEVMTY and DEVSTY are the basenames of the master and slave ptys */
  133. X/* respectively. They must each end with two spaces, filled in with */
  134. X/* characters from PTY1 and PTY2 respectively. If your ptys aren't */
  135. X/* labelled by this convention, I'm surprised you have anything working; */
  136. X/* either set up a new pty bank with normal names or change the pty code */
  137. X/* that allocates ptys. Note that convention allows you to only have */
  138. X/* some of a pty bank, as long as one of them is there; the first letter */
  139. X/* in PTY2 must indicate that one. */
  140. X
  141. X/* The order of PTY1 and PTY2 is the pty searching order. pty allows */
  142. X/* (and, as a break from tradition, uses by default) random searches, */
  143. X/* starting from random spots in PTY1 and PTY2 rather than the beginning. */
  144. X/* This has several good effects, although you may think utmp will look */
  145. X/* a bit ugly. */
  146. X
  147. X/* If you want to gradually convert your system to using this program, */
  148. X/* PTY1 and PTY2 shouldn't reference all your ptys. Instead, pick a */
  149. X/* large enough subset of your ptys to be usable, and try things out */
  150. X/* with just those. If everything works and you like pty's capabilities, */
  151. X/* remove your old ptys, or recompile pty to reference all of them. */
  152. X
  153. X/* TTYNAMELEN should be the maximum length of a tty (not just pty!) */
  154. X/* name. TTYNAMELEN shouldn't have to be there; it's used to work */
  155. X/* around some fundamental failures in the current tty/pty model. */
  156. X
  157. X
  158. X/* Section 3: Logging. */
  159. X
  160. X#ifndef PTYUTMP_FILE
  161. X#define PTYUTMP_FILE "/etc/utmp"
  162. X#endif
  163. X#ifndef PTYWTMP_FILE
  164. X#define PTYWTMP_FILE "/usr/adm/wtmp"
  165. X#endif
  166. X#ifndef PTYUTMP_OFFSET
  167. X#define PTYUTMP_OFFSET 5
  168. X#endif
  169. X#ifndef PTYWTMP_OFFSET
  170. X#define PTYWTMP_OFFSET PTYUTMP_OFFSET
  171. X#endif
  172. X#ifndef PTYUTMP_HOST
  173. X#define PTYUTMP_HOST "pty"
  174. X#endif
  175. X#ifndef PTYWTMP_HOST
  176. X#define PTYWTMP_HOST PTYUTMP_HOST
  177. X#endif
  178. X#ifndef PTYUTMP_SWHOST
  179. X#define PTYUTMP_SWHOST PTYUTMP_HOST
  180. X#endif
  181. X#ifndef PTYWTMP_SWHOST
  182. X#define PTYWTMP_SWHOST "pty-sessuser"
  183. X#endif
  184. X
  185. X/* These are straightforward. FILE is where you want the logs. utmp and */
  186. X/* wtmp are about as sensible as /etc/passwd and unfortunately just as */
  187. X/* popular; typically they're in /etc/utmp and /usr/adm/wtmp, and the */
  188. X/* utility programs in this package support that convention. (wtmp logs */
  189. X/* all ins and outs. utmp only has one entry per line, namely the last */
  190. X/* wtmp entry for it.) OFFSET is the number of chars from a pty extension */
  191. X/* to remove from a log entry; usually this is 5, to make /dev/ttyxx into */
  192. X/* ttyxx. Finally, HOST is the name that you want in the ``remote'' field */
  193. X/* of the log; that field is rather illogical, but it's there. */
  194. X
  195. X/* SWHOST is a variant of HOST, for what's logged upon a session uid */
  196. X/* switch. */
  197. X
  198. X/* If you're using pty under telnet/login/whatever, which do their own */
  199. X/* utmp and wtmp handling, then pty will usually have -xUW, so these */
  200. X/* defines aren't too important. Except for SWHOST, which is necessary */
  201. X/* for sessuser's action to make sense. */
  202. X
  203. X
  204. X/* Section 4: Protection. */
  205. X
  206. X#ifndef USEDPTYMODE
  207. X#define USEDPTYMODE 0600
  208. X#endif
  209. X#ifndef UNUSEDPTYMODE
  210. X#define UNUSEDPTYMODE 0600
  211. X#endif
  212. X#ifndef PTYOWNER
  213. X#define PTYOWNER euid
  214. X#endif
  215. X#ifndef PTYGROUP
  216. X#define PTYGROUP 4
  217. X#endif
  218. X
  219. X/* pty -xc will change the owner of the pty back to PTYOWNER after the */
  220. X/* child has exited. This should be euid, for the effective uid of the */
  221. X/* pty process. If a user runs pty as himself, he won't get to change */
  222. X/* the owner of the pseudo-terminal in the first place. */
  223. X
  224. X/* PTYGROUP should be the ``tty'' group in /etc/group, normally 4. All */
  225. X/* ptys and ttys should be in this group at all times. */
  226. X
  227. X/* USEDPTYMODE is the mode of ptys while they're being used. 600 is a */
  228. X/* good choice; it means messages off. If you want msgs y by default, */
  229. X/* try 620. Don't use the old 622: it's exceedingly insecure. */
  230. X
  231. X/* UNUSEDPTYMODE is the mode of ptys while they're unused. Traditionally */
  232. X/* this would be 666, so that any process needing a pty can just grab */
  233. X/* one. However, this leads to quite a few security holes. If you have */
  234. X/* lots of programs like emacs that really, really, really want to use */
  235. X/* ptys and don't support this interface, try 0660, and make those */
  236. X/* programs setgid tty. Otherwise, stick to 0600. */
  237. X
  238. X
  239. X/* Section 5: Other. */
  240. X
  241. X#ifndef SIGRET_TYPE
  242. X#define SIGRET_TYPE int
  243. X#endif
  244. X
  245. X#ifndef OUTBUFSIZE
  246. X#define OUTBUFSIZE 16384
  247. X#endif
  248. X
  249. X#ifndef GENERIC
  250. X#define GENERIC char
  251. X#endif
  252. X
  253. X#ifdef TTY_AUXCHARS
  254. X#define USESTAT
  255. X#endif
  256. X
  257. X/* SIGRET_TYPE is the type returned by signal handlers. Logically, it */
  258. X/* should be void, but C and signals were around before void was. */
  259. X
  260. X/* OUTBUFSIZE is the size of the extra buffers provided by pty, both */
  261. X/* for data coming in to the pseudo-terminal and for data going out. */
  262. X
  263. X/* It should be possible to cast any pointer to a GENERIC * pointer */
  264. X/* and back. Again, void makes the most sense and is the best choice */
  265. X/* under ANSI, but char is correct and much more portable. */
  266. X
  267. X/* Setting USESTAT is necessary for systems supporting auxchars. */
  268. X
  269. X
  270. X/* Section 6: Sanity checks. */
  271. X
  272. X#ifdef NO_UNIXSOCKS
  273. X#define NO_FDPASSING
  274. X#define NO_SESSION
  275. X#endif
  276. X
  277. X#ifdef NO_SESSION
  278. X#ifdef MUST_SESSION
  279. X#undef MUST_SESSION
  280. X#endif
  281. X#endif
  282. X
  283. X#ifdef NO_UTMP
  284. X#ifdef MUST_UTMP
  285. X#undef MUST_UTMP
  286. X#endif
  287. X#endif
  288. X
  289. X#ifdef NO_WTMP
  290. X#ifdef MUST_WTMP
  291. X#undef MUST_WTMP
  292. X#endif
  293. X#endif
  294. X
  295. X#ifdef NO_CHOWN
  296. X#ifdef MUST_CHOWN
  297. X#undef MUST_CHOWN
  298. X#endif
  299. X#endif
  300. X
  301. X#endif
  302. END_OF_FILE
  303.   if test 9610 -ne `wc -c <'config.h'`; then
  304.     echo shar: \"'config.h'\" unpacked with wrong size!
  305.   fi
  306.   # end of 'config.h'
  307. fi
  308. if test -f 'logs.c' -a "${1}" != "-c" ; then 
  309.   echo shar: Will not clobber existing file \"'logs.c'\"
  310. else
  311.   echo shar: Extracting \"'logs.c'\" \(1853 characters\)
  312.   sed "s/^X//" >'logs.c' <<'END_OF_FILE'
  313. X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
  314. X
  315. X#include "config.h"
  316. X#include "logs.h"
  317. X#include "file.h"
  318. X#include <utmp.h>
  319. X#include <strings.h>
  320. X
  321. X/* utmp and wtmp are about as sensible as /etc/passwd. */
  322. X
  323. X/* We never bother to shrink /etc/utmp. */
  324. X
  325. Xextern long time();
  326. X
  327. Xlong now()
  328. X{
  329. X return time((long *) 0);
  330. X}
  331. X
  332. Xint utmp(line,name,host,date)
  333. Xchar *line;
  334. Xchar *name;
  335. Xchar *host;
  336. Xlong date;
  337. X{
  338. X struct utmp ut;
  339. X struct utmp xt;
  340. X int fd;
  341. X int i;
  342. X int j;
  343. X
  344. X /* only use of strncpy, ever */
  345. X (void) strncpy(ut.ut_line,line,sizeof(ut.ut_line));
  346. X (void) strncpy(ut.ut_name,name,sizeof(ut.ut_name));
  347. X (void) strncpy(ut.ut_host,host,sizeof(ut.ut_host));
  348. X ut.ut_time = date;
  349. X
  350. X fd = open(PTYUTMP_FILE,O_RDWR);
  351. X if (fd == -1)
  352. X   return -1;
  353. X j = i = 0;
  354. X while (read(fd,(char *) &xt,sizeof(xt)) == sizeof(xt))
  355. X  {
  356. X   i++;
  357. X   if (strncmp(xt.ut_line,ut.ut_line,sizeof(ut.ut_line)) == 0)
  358. X    {
  359. X     j = i;
  360. X     break;
  361. X    }
  362. X  }
  363. X if (j)
  364. X  {
  365. X   if (lseek(fd,(long) ((j - 1) * sizeof(xt)),L_SET) == -1)
  366. X    {
  367. X     (void) close(fd);
  368. X     return -1;
  369. X    }
  370. X  }
  371. X else
  372. X  {
  373. X   /* We have to reopen to avoid a race with other end-of-utmp entries. */
  374. X   (void) close(fd);
  375. X   if ((fd = open(PTYUTMP_FILE,O_RDWR | O_APPEND)) == -1)
  376. X     return -1;
  377. X  }
  378. X if (write(fd,(char *) &ut,sizeof(ut)) < sizeof(ut))
  379. X  {
  380. X   (void) close(fd);
  381. X   return -1;
  382. X  }
  383. X (void) close(fd);
  384. X return 0;
  385. X}
  386. X
  387. Xint wtmp(line,name,host,date)
  388. Xchar *line;
  389. Xchar *name;
  390. Xchar *host;
  391. Xlong date;
  392. X{
  393. X struct utmp wt;
  394. X int fd;
  395. X
  396. X (void) strncpy(wt.ut_line,line,sizeof(wt.ut_line));
  397. X (void) strncpy(wt.ut_name,name,sizeof(wt.ut_name));
  398. X (void) strncpy(wt.ut_host,host,sizeof(wt.ut_host));
  399. X wt.ut_time = date;
  400. X
  401. X fd = open(PTYWTMP_FILE,O_WRONLY | O_APPEND);
  402. X if (fd == -1)
  403. X   return -1;
  404. X if (write(fd,(char *) &wt,sizeof(wt)) < sizeof(wt))
  405. X  {
  406. X   (void) close(fd);
  407. X   return -1;
  408. X  }
  409. X (void) close(fd);
  410. X return 0;
  411. X}
  412. END_OF_FILE
  413.   if test 1853 -ne `wc -c <'logs.c'`; then
  414.     echo shar: \"'logs.c'\" unpacked with wrong size!
  415.   fi
  416.   # end of 'logs.c'
  417. fi
  418. if test -f 'pty.1' -a "${1}" != "-c" ; then 
  419.   echo shar: Will not clobber existing file \"'pty.1'\"
  420. else
  421.   echo shar: Extracting \"'pty.1'\" \(12049 characters\)
  422.   sed "s/^X//" >'pty.1' <<'END_OF_FILE'
  423. X.TH pty 1
  424. X.SH NAME
  425. Xpty \- run a program under a pseudo-terminal session
  426. X.SH SYNTAX
  427. Xpty
  428. X[
  429. X\fB\-qQvdDe3EjJsStT0\fI
  430. X] [
  431. X\fB\-F\fI
  432. X] [
  433. X\fB\-f\fIn
  434. X] [
  435. X\fB\-p\fI[cCdDeEnNrRsS0]
  436. X] [
  437. X\fB\-x\fI[cCeEnNoOrRsSuUwWxX]
  438. X] [
  439. X\fB\-ACHUVW\fI
  440. X]
  441. Xprogram
  442. X[
  443. Xarg ...
  444. X]
  445. X.SH DESCRIPTION
  446. X.I pty
  447. Xdetaches itself from its original
  448. Xterminal,
  449. Xallocates a pseudo-terminal,
  450. Xand runs
  451. X.I program
  452. Xon that pseudo-terminal
  453. Xwith any given arguments.
  454. X.I pty
  455. Xlets you easily disconnect from and reconnect to
  456. Xsessions;
  457. Xit has over fifty options for precise control,
  458. Xand is meant to act as the sole interface
  459. Xbetween pseudo-terminals and the rest of the system.
  460. X.PP
  461. XThere are a few very common invocations of
  462. X.I pty.
  463. XThe most common is just
  464. X.I pty program,
  465. Xwith no options;
  466. Xthis has several effects as described below.
  467. X.I pty \-s program
  468. Xsets up a disconnectable session;
  469. Xit is described further in
  470. X.I sess(1).
  471. X.I pty \-0 program
  472. Xisolates the rest of the world from
  473. X.I program
  474. Xin several ways;
  475. Xit is described further in
  476. X.I condom(1).
  477. X.PP
  478. XThe two next most commonly used options
  479. Xare 
  480. X.I\-d,
  481. Xif
  482. X.I pty
  483. Xis started without a controlling terminal;
  484. Xand
  485. X.I\-xu,
  486. Xwhich makes an entry in
  487. X/etc/utmp.
  488. X.PP
  489. XSome programs (such as
  490. X.I vi)
  491. Xdon't like taking input or output
  492. Xfrom a pipe; under
  493. X.I pty,
  494. Xthey won't notice a thing.
  495. XOther programs buffer as much output as possible
  496. Xif they're in a pipe;
  497. Xunder
  498. X.I pty,
  499. Xthey'll buffer at most a line of output.
  500. X.I pty
  501. Xis very careful to restore terminal modes upon
  502. Xstopping or exiting;
  503. Xa careless
  504. X.I program
  505. Xis shielded from your terminal.
  506. XOtherwise,
  507. X.I pty program
  508. Xshould feel just like
  509. X.I program.
  510. X.PP
  511. X.I pty
  512. Xchanges the original terminal to character-at-a-time
  513. X(raw, cbreak, and noecho) mode; it sets the pseudo-terminal to
  514. Xthe original mode. When
  515. X.I program
  516. Xfinishes,
  517. X.I pty
  518. Xwill set the original terminal back to its original mode.
  519. XAny mode changes on the pseudo-terminal will be lost.
  520. X.PP
  521. X.I pty
  522. Xsets file descriptor 0 to input from the
  523. Xpseudo-terminal, 1 and 2 to output.
  524. X.I pty
  525. Xalso supports the ``3 is /dev/tty'' convention:
  526. Xit sets up file descriptor 3 for input from, output to,
  527. Xand terminal commands for
  528. X/dev/tty
  529. X(not the original tty, but the pseudo tty).
  530. X.PP
  531. XOptions
  532. X.B ACHUVW
  533. Xprint the authorship notice,
  534. Xcopyright notice,
  535. Xhelp notice,
  536. Xshort usage summary,
  537. Xversion number,
  538. Xand warranty information respectively.
  539. X.PP
  540. X.I pty
  541. Xhas quite a few flags,
  542. Xprocessed left to right:
  543. X.TP 12
  544. X\fB\-d\fI
  545. X.I pty
  546. Xwill assume it is already detached from the terminal.
  547. XThis forces
  548. X.B\-T;
  549. Xit sets but doesn't force
  550. X.B\-J.
  551. XAlso, instead of copying pseudo-terminal modes from
  552. Xthe original terminal,
  553. X.I pty
  554. Xwill set up a generic new-discipline line-at-a-time mode.
  555. X.TP
  556. X\fB\-D\fI
  557. X.I pty
  558. Xwill assume that it is attached to a terminal (default).
  559. XThis sets
  560. X.B\-jt.
  561. X.TP
  562. X\fB\-e\fI
  563. XPreserve
  564. Xstandard error (file descriptor 2)
  565. Xand standard tty (file descriptor 3).
  566. X.TP
  567. X\fB\-3\fI
  568. XPreserve fd 3, but point fd 2 at the pseudo-terminal.
  569. X.TP
  570. X\fB\-E\fI
  571. XDirect both file descriptors to the pseudo-terminal (default).
  572. X(Actually,
  573. X.I pty
  574. Xwill point standard error at the tty by name,
  575. Xbut fd 3 at /dev/tty,
  576. Xso that various
  577. X.I ioctl()
  578. Xcommands on fd 3 will work.)
  579. XAlso close all higher-numbered file descriptors.
  580. X.TP
  581. X\fB\-j\fI
  582. XJob control (default): When
  583. X.I program
  584. Xstops,
  585. X.I pty
  586. Xstops.
  587. XWhen 
  588. X.I pty
  589. Xis restarted,
  590. Xit restarts
  591. X.I program.
  592. X.TP
  593. X\fB\-J\fI
  594. XNo job control.
  595. XIf
  596. X.I program
  597. Xstops,
  598. X.I pty
  599. Xwill ignore it
  600. X(though it will always restart it upon a reconnect).
  601. XThis behavior is much less
  602. Xantisocial than
  603. Xthe behavior of the previous
  604. X.I pty
  605. Xversion.
  606. X.TP
  607. X\fB\-t\fI
  608. X.I pty
  609. Xwill set the
  610. Xoriginal terminal to
  611. Xno-echo, character-at-a-time mode (default).
  612. X.TP
  613. X\fB\-T\fI
  614. X.I pty
  615. Xwill not touch the original terminal, if there is one.
  616. XIt is always dangerous to put two programs in a pipe if both
  617. Xchange tty modes;
  618. X.I pty,
  619. X.I vi,
  620. Xand
  621. X.I more
  622. Xare examples of such programs. If you use
  623. X.I pty
  624. Xin a pipe
  625. Xwith another tty-mode-changing program,
  626. Xmake sure to specify
  627. X.B\-0
  628. X(which is an abbreviation for
  629. X.B\-eSTp0)
  630. Xso that
  631. X.I pty
  632. Xwill neither affect nor be affected by the other program.
  633. XIf you use a pipe of ptys,
  634. Xyou should probably specify
  635. X.B\-0
  636. Xin all but one.
  637. X.TP
  638. X\fB\-s\fI
  639. XSession.
  640. XWhen the connection is hung up or manually disconnected,
  641. X.I pty
  642. Xwill patiently wait for a
  643. Xreconnection.
  644. X.I program
  645. Xwon't notice a thing.
  646. X.B\-s
  647. Xsets but does not force
  648. X.B\-xu.
  649. XIt forces
  650. X.B\-E.
  651. X.TP
  652. X\fB\-S\fI
  653. XNo session (default).
  654. XWhen the connection is hung up,
  655. X.I pty
  656. Xwill send a HUP to
  657. X.I program.
  658. X.B\-S
  659. Xsets but does not force
  660. X.B\-xU.
  661. X.TP
  662. X\fB\-q\fI
  663. XQuiet.
  664. X.I pty
  665. Xwill print absolutely nothing on standard error.
  666. XIt will communicate strange events through its exit code.
  667. X.TP
  668. X\fB\-Q\fI
  669. XNot quiet (default).
  670. X.I pty
  671. Xwill generate bits of chatter about interesting
  672. Xevents.
  673. X.TP
  674. X\fB\-v\fI
  675. XVerbose.
  676. X.I pty
  677. Xwill blabber on and on and on and on and on and on and on and on.
  678. XIt keeps going,
  679. Xand going,
  680. Xand going,
  681. Xand going ...
  682. X.TP
  683. X\fB\-f\fIfd
  684. XPass the master and slave sides of the pseudo-terminal
  685. Xup in file descriptor
  686. X.I fd.
  687. XThis is only available if your machine supports descriptor passing.
  688. X
  689. XThe protocol, from the point of view of the receiver (``controller''),
  690. Xis to pty_getch a character off the other side
  691. Xof the passing descriptor, perhaps check that it is a G,
  692. Xand pty_putgetint a G for the process id of the signaller
  693. X(the process to recieve a HUP if the connection drops);
  694. Xpty_getch a character, perhaps check that it is m,
  695. Xand pty_putgetfd an m for the master side of the pseudo-terminal;
  696. Xand similarly for s and the slave side. (These functions are all
  697. Xavailable in sock.c in the
  698. X.I pty
  699. Xsource code.)
  700. X
  701. XWhen the connection is dropped,
  702. X.I pty
  703. Xwill send up a period,
  704. Xfollowed by one pid and two new descriptors as above
  705. Xif it reconnects.
  706. XIn the meantime, the controller has full responsibility for
  707. Xperforming terminal I/O.
  708. X.TP
  709. X\fB\-F\fI
  710. XDo not pass anything (default).
  711. X.TP
  712. X\fB\-p\fImmm
  713. XSet the
  714. Xpseudo-terminal to modes specified by
  715. X.I m.
  716. XUnder
  717. X.B\-d,
  718. Xdefaults are taken from the
  719. Xcurrent terminal;
  720. Xunder
  721. X.B\-D,
  722. Xdefaults are as below.
  723. XPredefined modes:
  724. X.RS
  725. X.TP 5
  726. X.I c
  727. XSet cbreak (character-at-a-time) mode.
  728. X.TP
  729. X.I C
  730. XDo not set cbreak mode (default). 
  731. X.TP
  732. X.I d
  733. XUse the new discipline (default, breaking with tradition).
  734. X.TP
  735. X.I D
  736. XUse the old discipline, without job control or other fancy tty features.
  737. X.TP
  738. X.I e
  739. XEcho characters (default).
  740. X.TP
  741. X.I E
  742. XDo not echo.
  743. X.TP
  744. X.I n
  745. XChange return to newline (default).
  746. X.TP
  747. X.I N
  748. XDo not change return to newline.
  749. X.TP
  750. X.I r
  751. XSet raw mode: do not produce signals, and pass eight-bit characters.
  752. X.TP
  753. X.I R
  754. XSet non-raw (``cooked'') mode (default).
  755. X.TP
  756. X.I s
  757. XSet line editing modes appropriate for a screen (default).
  758. X.TP
  759. X.I S
  760. XDo not set crt line editing modes.
  761. X.TP
  762. X.I 0
  763. XAn abbreviation for pcEN.
  764. X.RE
  765. X.TP
  766. X\fB\-x\fIsss
  767. XUse security, experimental, or extended measures specified by
  768. X.I s.
  769. XSome of these may be required or disabled by your system administrator.
  770. XPredefined values:
  771. X.RS
  772. X.TP 5
  773. X.I c
  774. XChange the ownership and protections of the pty appropriately.
  775. XThis reflects several errors in the
  776. X.I pty
  777. Xmodel, but it's customary.
  778. X.TP
  779. X.I C
  780. XDo not change pty ownership (default).
  781. X.TP
  782. X.I e
  783. XOpen stderr write-only to the pseudo-terminal.
  784. XThis should be default, but such programs as
  785. X.I csh
  786. Xand
  787. X.I more
  788. Xinsist on reading from stderr and dying horribly
  789. Xif they fail.
  790. X.B\-xe
  791. Xis useless under
  792. X.B\-e.
  793. X.TP
  794. X.I E
  795. XOpen stderr for reading and writing (default).
  796. X.TP
  797. X.I u
  798. XEnter login name into /etc/utmp.
  799. XAs a rule of thumb,
  800. Xyou should do this for interactive sessions.
  801. X.TP
  802. X.I n
  803. XUse some heuristics to try to figure out if someone
  804. Xhas the pty open (default).
  805. X.TP
  806. X.I N
  807. XDon't worry about pre-opened ptys.
  808. X.TP
  809. X.I o
  810. XSame as
  811. X.B\-xn,
  812. Xbut go on to the next pseudo-terminal
  813. Xif this one is open.
  814. X.TP
  815. X.I O
  816. XDon't skip pre-opened ptys.
  817. X.TP
  818. X.I r
  819. XRandom pseudo-terminal searching (default).
  820. XThis can provide a huge boost to speed and security.
  821. XIt hasn't been used because programmers don't realize
  822. Xthe virtues of modularity, are consequently too lazy to
  823. Xwrite something like
  824. X.I pty,
  825. Xand don't want to take the effort for random pty searching
  826. Xin every program that uses pseudo-terminals.
  827. X.TP
  828. X.I R
  829. XStraight pty searching, from the bottom on up.
  830. X.TP
  831. X.I s
  832. XSetuid (default).
  833. X.I pty 
  834. Xwill use a common directory
  835. Xfor storing session information.
  836. X.TP
  837. X.I S
  838. XNot setuid.
  839. X.I pty
  840. Xwill revoke all privileges and
  841. Xuse a subdirectory of your HOME directory.
  842. X.TP
  843. X.I U
  844. XDo not use utmp (default).
  845. X.TP
  846. X.I w
  847. XMake an entry in /usr/adm/wtmp.
  848. XThis probably isn't a good idea for general use,
  849. Xas
  850. Xconnection time recorded in
  851. X.I wtmp
  852. Xis often pressed into unfortunate service as
  853. Xa senseless basis for charged computer time.
  854. X.TP
  855. X.I W
  856. XDo not use wtmp (default).
  857. X.TP
  858. X.I x
  859. XSet exclusive use on the pty.
  860. XNo processes can open the pty after this;
  861. X.I program
  862. Xcan't even reopen
  863. X/dev/tty!
  864. X(It can use file descriptor 3 instead.)
  865. XThis can be very important for security when
  866. X.I pty
  867. Xhas not been installed by the system administrator.
  868. XIt should be set all the time, but
  869. Xtoo many programs rely on a filename for the terminal.
  870. X.TP
  871. X.I X
  872. XDo not set exclusive use (default).
  873. X.RE
  874. X.PP
  875. X.SH DIAGNOSTICS
  876. X.TP
  877. Xvarious usage messages
  878. XExit 1.
  879. X.TP
  880. X.I fatal: cannot find control terminal
  881. X.I pty
  882. Xis unable to find its current control terminal.
  883. XExit 2.
  884. X.TP
  885. X.I fatal: cannot get current tty modes
  886. XThis shouldn't happen.
  887. XExit 3.
  888. X.TP
  889. X.I fatal: cannot set modes of original tty
  890. XThis shouldn't happen.
  891. XExit 4.
  892. X.TP
  893. X.I fatal: no ptys available
  894. XSelf-explanatory.
  895. XExit 5.
  896. X.TP
  897. X.I fatal: can't fcntl pty
  898. X.TP
  899. X.I fatal: slave unopenable
  900. XThere's a serious problem with your pseudo-terminal setup.
  901. XReport this error to your system administrator.
  902. XExit 6.
  903. X.TP
  904. X.I fatal: cannot fork
  905. X.I pty
  906. Xhas run out of processes.
  907. XExit 7.
  908. X.TP
  909. X.I fatal: cannot change to session directory
  910. XSelf-explanatory.
  911. XExit 8.
  912. X.TP
  913. X.I fatal: cannot open internal pipe.
  914. XCannot happen.
  915. XExit 10.
  916. X.TP
  917. X.I fatal: socket read error
  918. XSelf-explanatory. Exit 11.
  919. X.TP
  920. X.I fatal: socket write error
  921. XSelf-explanatory. Exit 12.
  922. X.TP
  923. X.I fatal: input read error
  924. XSelf-explanatory. Exit 13.
  925. X.TP
  926. X.I fatal: output write error
  927. XSelf-explanatory. Exit 14.
  928. X.SH RESTRICTIONS
  929. XThere are many security problems
  930. Xand limitations associated with BSD-style ttys.
  931. X.I pty
  932. Xdoes its best to avoid them,
  933. Xbut a Streams-based system would be much better.
  934. XThe author plans to rewrite
  935. X.I pty,
  936. Xwith the same interface,
  937. Xfor a Streams system.
  938. X.PP
  939. XThe current
  940. X.B\-J
  941. Xbehavior is a bit dull.
  942. XI wish programs would use the job control
  943. Xmechanisms more cleanly.
  944. X.PP
  945. XTo avoid a race condition,
  946. X.I pty
  947. Xchews up a tiny bit more CPU time than it should every
  948. Xtime
  949. X.I program
  950. Xis stopped and then restarted.
  951. X.PP
  952. XIf
  953. X.I program
  954. Xcloses the pseudo-terminal but doesn't die,
  955. X.I pty
  956. Xwill wait for it, even though it will have no further interaction with
  957. Xit.
  958. X.PP
  959. X.I pty
  960. Xdoes not provide any way to loudly proclaim that
  961. X.I program
  962. Xdoesn't exist.
  963. XIt simply dies quietly.
  964. X.PP
  965. XBecause of BSD's ridiculous controlling terminal mechanism,
  966. Xa reconnecting
  967. X.I pty
  968. Xhas to
  969. Xpass the name of its original terminal
  970. Xto the session underneath.
  971. XSince there is no portable way to find out that name,
  972. X.I pty
  973. Xrequires that some file descriptor be open, pointing
  974. Xto the current terminal
  975. X.I (not
  976. X/dev/tty!).
  977. X(More precisely,
  978. Xthe highest-numbered file descriptor that
  979. Xis a terminal file but not /dev/tty
  980. Xmust be the real name of the original controlling terminal.
  981. XThat's one good use for fd 3.
  982. XIf that file descriptor is some other terminal,
  983. Xthe reconnect will fail miserably.)
  984. X.SH BUGS
  985. XNone known, but they're probably hiding somewhere.
  986. XIt is the author's opinion that
  987. X.I pty
  988. Xis the ``right'' way to handle pseudo-terminals;
  989. Xif programmers use
  990. X.I pty
  991. Xinstead of writing equivalent code in each program,
  992. Xthen everything becomes much more portable and bug-free.
  993. XAs different systems provide different
  994. Xpseudo-terminal mechanisms,
  995. Xthe only program that need be changed is
  996. X.I pty.
  997. X(This is called ``modularity,''
  998. X``interface design,''
  999. Xor ``outside-in programming.'')
  1000. X.SH MACHINES
  1001. X.I pty
  1002. Xhas been tested thoroughly
  1003. Xon several BSD 4.3-based machines
  1004. Xand tested on
  1005. Xseveral BSD 4.2-based machines.
  1006. X.SH VERSION
  1007. Xpty version 3.001, dated August 21, 1990.
  1008. X.SH AUTHOR
  1009. XCopyright 1990, Daniel J. Bernstein.
  1010. X.SH "SEE ALSO"
  1011. Xpty(4),
  1012. Xtty(4)
  1013. END_OF_FILE
  1014.   if test 12049 -ne `wc -c <'pty.1'`; then
  1015.     echo shar: \"'pty.1'\" unpacked with wrong size!
  1016.   fi
  1017.   # end of 'pty.1'
  1018. fi
  1019. if test -f 'sigler.c' -a "${1}" != "-c" ; then 
  1020.   echo shar: Will not clobber existing file \"'sigler.c'\"
  1021. else
  1022.   echo shar: Extracting \"'sigler.c'\" \(8120 characters\)
  1023.   sed "s/^X//" >'sigler.c' <<'END_OF_FILE'
  1024. X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
  1025. X
  1026. X#include "config.h"
  1027. X#include <sys/types.h>
  1028. X#include <sys/time.h>
  1029. X#include <stdio.h>
  1030. X#include <strings.h>
  1031. X#include "pty.h"
  1032. X#include "sigler.h"
  1033. X#include "sig.h"
  1034. X#include "file.h"
  1035. X#include "sock.h"
  1036. X#include "err.h"
  1037. X#include "misc.h"
  1038. X
  1039. X/* General XXX: In failure cases, sig.* isn't always removed. */
  1040. X
  1041. Xstatic char *glfnsty;
  1042. X
  1043. Xstatic int masterpid;
  1044. X
  1045. Xstatic int flagmaster = 1;
  1046. Xstatic int flagcont = 0;
  1047. Xstatic int pi[2];
  1048. X
  1049. Xstatic void deatherrp(i,s)
  1050. Xint i;
  1051. Xchar *s;
  1052. X{
  1053. X int e = errno;
  1054. X
  1055. X (void) kill(masterpid,SIGTERM);
  1056. X /* XXX: should wait while flagmaster */
  1057. X (void) tty_modifymodes(fdtty,&tmotty,&tmochartty);
  1058. X fatalerrp(i,s,e);
  1059. X}
  1060. X
  1061. Xstatic void finish(i)
  1062. Xsig_num i;
  1063. X{
  1064. X if (i == SIGTERM)
  1065. X  {
  1066. X   flagmaster = 0;
  1067. X   (void) write(pi[1],".",1);
  1068. X  }
  1069. X else
  1070. X   (void) write(pi[1],",",1);
  1071. X}
  1072. X
  1073. X/*ARGSUSED*/
  1074. Xstatic void sig_usr2(i)
  1075. Xsig_num i;
  1076. X{
  1077. X if (flagsession)
  1078. X  {
  1079. X   char fnsess[20];
  1080. X   int fdsess;
  1081. X   int newuid = uid;
  1082. X   char newsuid[10];
  1083. X
  1084. X   /* XXX: We should have some error recovery here! */
  1085. X
  1086. X   /* We can make quite a few assumptions, because we only get USR2 */
  1087. X   /* forwarded from the master. */
  1088. X
  1089. X   (void) sprintf(fnsess,"sess.%s",glfnsty + sizeof(DEVSTY) - 3);
  1090. X   if ((fdsess = open(fnsess,O_RDONLY,0600)) != -1)
  1091. X    {
  1092. X     (void) read(fdsess,(char *) &newuid,sizeof(int));
  1093. X     (void) sprintf(newsuid,"%d",newuid);
  1094. X
  1095. X     (void) chdir("..");
  1096. X     (void) chdir(newsuid);
  1097. X  
  1098. X     uid = newuid;
  1099. X     (void) setreuid(uid,euid);
  1100. X     (void) close(fdsess);
  1101. X    }
  1102. X  }
  1103. X}
  1104. X
  1105. X/*ARGSUSED*/
  1106. Xstatic void sig_cont(i)
  1107. Xsig_num i;
  1108. X{
  1109. X flagcont = 1;
  1110. X (void) write(pi[1]," ",1);
  1111. X}
  1112. X
  1113. Xvoid sigler(fnsty,master)
  1114. Xchar *fnsty;
  1115. Xint master;
  1116. X{
  1117. X char ch;
  1118. X char path[100];
  1119. X int fd = -1;
  1120. X char *ttyn;
  1121. X char fntty[TTYNAMELEN];
  1122. X
  1123. X glfnsty = fnsty;
  1124. X masterpid = master;
  1125. X /* pid = getpid() is already true */
  1126. X (void) sprintf(path,"sig.%s",fnsty + sizeof(DEVSTY) - 3);
  1127. X (void) unlink(path);
  1128. X
  1129. X (void) close(fdmty);
  1130. X (void) close(fdsty);
  1131. X if (fdre != -1) (void) close(fdre);
  1132. X
  1133. X if (pipe(pi) == -1) /* clumsy, but stops several races */
  1134. X   /* This is absolutely impossible. fdmty and fdsty must have been open */
  1135. X   /* before this, and we just closed them, so there must be two fds */
  1136. X   /* available for the pipe. */
  1137. X   deatherrp(10,"pty: fatal: cannot open internal pipe");
  1138. X (void) fcntl(pi[1],F_SETFL,FNDELAY);
  1139. X
  1140. X sig_ignore(SIGCHLD);
  1141. X sig_ignore(SIGXCPU);
  1142. X sig_ignore(SIGXFSZ);
  1143. X sig_ignore(SIGPROF);
  1144. X sig_ignore(SIGVTALRM);
  1145. X
  1146. X sig_default(SIGEMT); /* XXX: really dump? */
  1147. X sig_default(SIGIOT);
  1148. X sig_default(SIGILL);
  1149. X sig_default(SIGSEGV);
  1150. X
  1151. X sig_default(SIGTTOU);
  1152. X sig_default(SIGTTIN);
  1153. X sig_default(SIGTSTP);
  1154. X sig_default(SIGSTOP);
  1155. X
  1156. X sig_sethandler(SIGTERM,finish); sig_handle(SIGTERM);
  1157. X sig_sethandler(SIGINT,finish); sig_handle(SIGINT);
  1158. X sig_sethandler(SIGQUIT,finish); sig_handle(SIGQUIT);
  1159. X sig_sethandler(SIGHUP,finish); sig_handle(SIGHUP);
  1160. X sig_sethandler(SIGUSR1,finish); sig_handle(SIGUSR1); /* disconnect */
  1161. X
  1162. X sig_sethandler(SIGCONT,sig_cont); sig_handle(SIGCONT);
  1163. X
  1164. X sig_sethandler(SIGUSR2,sig_usr2); sig_handle(SIGUSR2);
  1165. X
  1166. X for (;;)
  1167. X  {
  1168. X   ch = '0';
  1169. X   if (flagcont)
  1170. X    {
  1171. X     flagcont = 0;
  1172. X     if (tty_modifymodes(fdtty,&tmochartty,&tmotty) == -1)
  1173. X       ; /* XXX: impossible, but what if it happens? */
  1174. X     (void) kill(masterpid,SIGUSR1); /* not CONT---see master.c's sig_cont() */
  1175. X    }
  1176. X#ifdef NO_FDPASSING
  1177. X   if (flagmaster == 2)
  1178. X    {
  1179. X     static fd_set rfds;
  1180. X     static fd_set wfds;
  1181. X     static int r;
  1182. X     static int w;
  1183. X     static char foobuf[OUTBUFSIZE];
  1184. X     int fdnum;
  1185. X     static char *s;
  1186. X
  1187. X     fdnum = fd; if (fdin > fdnum) fdnum = fdin;
  1188. X     if (pi[0] > fdnum) fdnum = pi[0]; fdnum++;
  1189. X
  1190. X     FD_ZERO(&rfds);
  1191. X     FD_ZERO(&wfds);
  1192. X     FD_SET(fd,&rfds);
  1193. X     FD_SET(fdin,&rfds);
  1194. X     FD_SET(pi[0],&rfds);
  1195. X
  1196. X     r = select(fdnum,&rfds,&wfds,(fd_set *) 0,(struct timeval *) 0);
  1197. X     if (r > 0)
  1198. X      {
  1199. X       if (FD_ISSET(fd,&rfds))
  1200. X    {
  1201. X     if ((r = read(fd,foobuf,OUTBUFSIZE)) == -1)
  1202. X       deatherrp(11,"pty: fatal: socket read error");
  1203. X     s = foobuf;
  1204. X     /* XXX: r can't be zero, but what if it is? */
  1205. X     while (r)
  1206. X      {
  1207. X       if ((w = write(fdout,s,r)) == -1)
  1208. X         deatherrp(14,"pty: fatal: output write error");
  1209. X       r -= w; s += w;
  1210. X      }
  1211. X    }
  1212. X       if (FD_ISSET(fdin,&rfds))
  1213. X    {
  1214. X     if ((r = read(fdin,foobuf,OUTBUFSIZE)) == -1)
  1215. X       deatherrp(13,"pty: fatal: input read error");
  1216. X     s = foobuf;
  1217. X     /* XXX: What if r is zero? Can't pass EOF, grrrr */
  1218. X     while (r)
  1219. X      {
  1220. X       if ((w = write(fd,s,r)) == -1)
  1221. X         deatherrp(12,"pty: fatal: socket write error");
  1222. X       r -= w; s += w;
  1223. X      }
  1224. X    }
  1225. X       if (FD_ISSET(pi[0],&rfds))
  1226. X     (void) read(pi[0],&ch,1);
  1227. X      }
  1228. X    }
  1229. X   else
  1230. X     (void) read(pi[0],&ch,1);
  1231. X#else
  1232. X   (void) read(pi[0],&ch,1);
  1233. X#endif
  1234. X   if ((ch == '.') || (ch == ','))
  1235. X    {
  1236. X     if (fd != -1)
  1237. X       (void) close(fd);
  1238. X     if (flagmaster)
  1239. X      {
  1240. X       if (kill(masterpid,SIGTERM) == -1)
  1241. X     flagmaster = 0; /* XXX */
  1242. X
  1243. X       if (fdpass != -1)
  1244. X     (void) write(fdpass,".",1);
  1245. X    
  1246. X       while (flagmaster)
  1247. X         ;
  1248. X       while (ch != '.')
  1249. X         (void) read(pi[0],&ch,1);
  1250. X      }
  1251. X
  1252. X     /* We don't test at this point whether the killing signal was a HUP. */
  1253. X     /* This means that hanging up on a reconnecting sigler won't stop */
  1254. X     /* the reconnect; instead, the new session will be instantly hung */
  1255. X     /* up. The USR1 used for a manual disconnect could be HUP for this */
  1256. X     /* reason. */
  1257. X     if (flagsession
  1258. X       &&((fd = open(path,O_RDONLY)) != -1)
  1259. X       &&(read(fd,fnsty,sizeof(DEVSTY) - 1) > 0))
  1260. X      {
  1261. X       warnerr2("pty: reconnecting to %s\r\n",fnsty);
  1262. X       (void) close(fd);
  1263. X       (void) unlink(path);
  1264. X       if ((fd = pty_writesock(fnsty)) == -1)
  1265. X     warnerr2("pty: reconnect failed: cannot talk to %s\r\n",fnsty);
  1266. X       else
  1267. X    {
  1268. X     if ((pty_getch(fd,&ch) != -1) && (ch == 'p'))
  1269. X       if (pty_putgetint(fd,'p',&masterpid) != -1)
  1270. X         do
  1271. X          {
  1272. X#ifdef NO_FDPASSING
  1273. X               if (fdtty != -1)
  1274. X        {
  1275. X                 if (!(ttyn = real_ttyname(fdtty))) break;
  1276. X             /* XXX: Should we NXCL here? */
  1277. X             (void) strncpy(fntty,ttyn,TTYNAMELEN - 1);
  1278. X                 if (pty_sendstr(fd,'s',fntty) == -1) break;
  1279. X             if (flagverbose)
  1280. X           warnerr2("pty: sent parent tty %s\r\n",fntty);
  1281. X        }
  1282. X#else
  1283. X           if (fdtty != -1)
  1284. X        {
  1285. X                 if (!(ttyn = real_ttyname(fdtty))) break;
  1286. X             /* XXX: Should we NXCL here? */
  1287. X             (void) strncpy(fntty,ttyn,TTYNAMELEN - 1);
  1288. X                 if (pty_sendstr(fd,'s',fntty) == -1) break;
  1289. X             if (flagverbose)
  1290. X             warnerr2("pty: sent parent tty %s\r\n",fntty);
  1291. X             /* We shouldn't have to send the parent tty name, */
  1292. X             /* but passing the fd alone doesn't set the control */
  1293. X             /* terminal of the receiver (grrrr), and a detached */
  1294. X             /* process effectively has no pgrp. Aargh. */
  1295. X        }
  1296. X
  1297. X           if (fdpass == -1)
  1298. X        {
  1299. X             if (pty_sendfd(fd,'0',&fdin) == -1) break;
  1300. X             if (pty_sendfd(fd,'1',&fdout) == -1) break;
  1301. X        }
  1302. X           else
  1303. X         if (pty_sendfd(fd,'f',&fdpass) == -1) break;
  1304. X           if (fdtty != -1)
  1305. X         if (pty_sendfd(fd,'t',&fdtty) == -1) break;
  1306. X#endif
  1307. X           if (pty_sendint(fd,'p',&pid) == -1) break;
  1308. X           if (pty_sendint(fd,'g',&pgrp) == -1) break;
  1309. X           if (pty_sendint(fd,'j',&flagjobctrl) == -1) break;
  1310. X           if (fdtty != -1)
  1311. X        {
  1312. X         if (pty_sendtty(fd,'c',&tmochartty) == -1) break;
  1313. X         if (pty_sendtty(fd,'n',&tmotty) == -1) break;
  1314. X        }
  1315. X           if (pty_putch(fd," ") == -1) break;
  1316. X#ifdef NO_FDPASSING
  1317. X           flagmaster = 2; /* Success, but pain coming up. */
  1318. X#else
  1319. X           flagmaster = 1; /* Successfully reconnected! */
  1320. X#endif
  1321. X          }
  1322. X         while(0);
  1323. X     if (flagmaster < 2)
  1324. X      {
  1325. X           (void) close(fd);
  1326. X       fd = -1;
  1327. X      }
  1328. X    }
  1329. X       if (flagmaster)
  1330. X    {
  1331. X     /* remake path for new pty */
  1332. X         (void) sprintf(path,"sig.%s",fnsty + sizeof(DEVSTY) - 3);
  1333. X         (void) unlink(path);
  1334. X     warnerr2("pty: successfully reconnected to %s\r\n",fnsty);
  1335. X    }
  1336. X       else
  1337. X     warnerr2("pty: reconnect to %s failed\r\n",fnsty);
  1338. X      }
  1339. X     if (!flagmaster)
  1340. X      {
  1341. X       if (tty_modifymodes(fdtty,&tmotty,&tmochartty) == -1)
  1342. X         warnerr2("%s","pty: can't restore tty modes\n"); /*XXX*/
  1343. X       fatal(0);
  1344. X       /*NOTREACHED*/
  1345. X      }
  1346. X    }
  1347. X  }
  1348. X}
  1349. END_OF_FILE
  1350.   if test 8120 -ne `wc -c <'sigler.c'`; then
  1351.     echo shar: \"'sigler.c'\" unpacked with wrong size!
  1352.   fi
  1353.   # end of 'sigler.c'
  1354. fi
  1355. if test -f 'sock.c' -a "${1}" != "-c" ; then 
  1356.   echo shar: Will not clobber existing file \"'sock.c'\"
  1357. else
  1358.   echo shar: Extracting \"'sock.c'\" \(5474 characters\)
  1359.   sed "s/^X//" >'sock.c' <<'END_OF_FILE'
  1360. X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
  1361. X
  1362. X#include "config.h"
  1363. X#include <sys/types.h>
  1364. X#include <sys/time.h>
  1365. X#ifndef NO_UNIXSOCKS
  1366. X#include <sys/socket.h>
  1367. X#include <sys/un.h>
  1368. X#ifndef NO_FDPASSING
  1369. X#include <sys/uio.h>
  1370. X#endif
  1371. X#include <stdio.h>
  1372. X#include <strings.h>
  1373. X#endif
  1374. X#include "sock.h"
  1375. X#include "tty.h"
  1376. X#include "err.h"
  1377. X
  1378. Xstatic int bufwrite(fd,buf,num)
  1379. Xint fd;
  1380. Xchar *buf;
  1381. Xint num;
  1382. X{
  1383. X int r;
  1384. X
  1385. X do
  1386. X  {
  1387. X   r = write(fd,buf,num);
  1388. X   if (r > 0)
  1389. X    {
  1390. X     buf += r;
  1391. X     num -= r;
  1392. X    }
  1393. X  }
  1394. X while ((num > 0) && ((r != -1) || (errno == EINTR)));
  1395. X return (r >= 0) ? 0 : -1;
  1396. X}
  1397. X
  1398. Xstatic int bufread(fd,buf,num)
  1399. Xint fd;
  1400. Xchar *buf;
  1401. Xint num;
  1402. X{
  1403. X int r;
  1404. X
  1405. X do
  1406. X  {
  1407. X   r = read(fd,buf,num);
  1408. X   if (r > 0)
  1409. X    {
  1410. X     buf += r;
  1411. X     num -= r;
  1412. X    }
  1413. X  }
  1414. X while ((num > 0) && ((r != -1) || (errno == EINTR)));
  1415. X /* Note that we ignore EOF. */
  1416. X return (r >= 0) ? 0 : -1;
  1417. X}
  1418. X
  1419. Xint pty_readsock(line,path)
  1420. Xchar *line;
  1421. Xchar *path;
  1422. X{
  1423. X#ifdef NO_UNIXSOCKS
  1424. X return -1;
  1425. X#else
  1426. X int s;
  1427. X struct sockaddr_un sa;
  1428. X
  1429. X if ((s = socket(AF_UNIX,SOCK_STREAM,0)) == -1)
  1430. X   return -1;
  1431. X sa.sun_family = AF_UNIX;
  1432. X (void) sprintf(sa.sun_path,"re.%s",line + sizeof(DEVSTY) - 3);
  1433. X (void) strcpy(path,sa.sun_path);
  1434. X (void) unlink(sa.sun_path);
  1435. X if (bind(s,(struct sockaddr *) &sa,strlen(sa.sun_path) + 2) == -1)
  1436. X   return -1;
  1437. X if (listen(s,5) == -1)
  1438. X   return -1;
  1439. X return s;
  1440. X#endif
  1441. X}
  1442. X
  1443. Xint pty_writesock(line)
  1444. Xchar *line;
  1445. X{
  1446. X#ifdef NO_UNIXSOCKS
  1447. X return -1;
  1448. X#else
  1449. X int s;
  1450. X struct sockaddr_un sa;
  1451. X
  1452. X if ((s = socket(AF_UNIX,SOCK_STREAM,0)) == -1)
  1453. X   return -1;
  1454. X sa.sun_family = AF_UNIX;
  1455. X (void) sprintf(sa.sun_path,"re.%s",line + sizeof(DEVSTY) - 3);
  1456. X if (connect(s,(struct sockaddr *) &sa,strlen(sa.sun_path) + 2) == -1)
  1457. X   return -1;
  1458. X (void) unlink(sa.sun_path);
  1459. X return s;
  1460. X#endif
  1461. X}
  1462. X
  1463. Xint pty_acceptsock(fd)
  1464. Xint fd;
  1465. X{
  1466. X#ifdef NO_UNIXSOCKS
  1467. X return -1;
  1468. X#else
  1469. X struct sockaddr_un sa;
  1470. X int salen = sizeof(sa);
  1471. X
  1472. X return accept(fd,(struct sockaddr *) &sa,&salen);
  1473. X#endif
  1474. X}
  1475. X
  1476. Xint pty_putgetonefd(fd,fp)
  1477. Xint fd;
  1478. Xint *fp;
  1479. X{
  1480. X#ifdef NO_FDPASSING
  1481. X return -1;
  1482. X#else
  1483. X struct msghdr msg[2];
  1484. X int acc[5];
  1485. X struct iovec i[2];
  1486. X
  1487. X msg[0].msg_name = 0;
  1488. X msg[0].msg_namelen = 0;
  1489. X msg[0].msg_iov = &i[0]; /* grrrr */
  1490. X msg[0].msg_iovlen = 0;
  1491. X msg[0].msg_accrights = (caddr_t) acc;
  1492. X msg[0].msg_accrightslen = 5 * sizeof(int);
  1493. X#ifdef USLEEP
  1494. X (void) usleep((unsigned) 100000);
  1495. X#else
  1496. X (void) sleep(1); /* XXX: work around fd passing bug */
  1497. X#endif
  1498. X if (recvmsg(fd,msg,0) == -1)
  1499. X   return -1;
  1500. X if (msg[0].msg_accrightslen != sizeof(int))
  1501. X   return -1;
  1502. X if (*fp != -1)
  1503. X   (void) close(*fp);
  1504. X *fp = acc[0]; /* yay! we've passed a file descriptor! */
  1505. X return 0;
  1506. X#endif
  1507. X}
  1508. X
  1509. Xint pty_putgetfd(fd,ch,fp)
  1510. Xint fd;
  1511. Xchar ch;
  1512. Xint *fp;
  1513. X{
  1514. X#ifdef NO_FDPASSING
  1515. X return -1;
  1516. X#else
  1517. X if (bufwrite(fd,&ch,1) < 0)
  1518. X   return -1;
  1519. X if (pty_putgetonefd(fd,fp) < 0)
  1520. X   return -1;
  1521. X if (bufwrite(fd,".",1) < 0)
  1522. X   return -1;
  1523. X return 0;
  1524. X#endif
  1525. X}
  1526. X
  1527. Xint pty_putgetint(fd,ch,ip)
  1528. Xint fd;
  1529. Xchar ch;
  1530. Xint *ip;
  1531. X{
  1532. X if (bufwrite(fd,&ch,1) < 0)
  1533. X   return -1;
  1534. X if (bufread(fd,(char *) ip,sizeof(int)) < 0)
  1535. X   return -1;
  1536. X if (bufwrite(fd,".",1) < 0)
  1537. X   return -1;
  1538. X return 0;
  1539. X}
  1540. X
  1541. Xint pty_putgetstr(fd,ch,str)
  1542. Xint fd;
  1543. Xchar ch;
  1544. Xchar str[TTYNAMELEN];
  1545. X{
  1546. X if (bufwrite(fd,&ch,1) < 0)
  1547. X   return -1;
  1548. X if (bufread(fd,str,TTYNAMELEN) < 0)
  1549. X   return -1;
  1550. X if (bufwrite(fd,".",1) < 0)
  1551. X   return -1;
  1552. X return 0;
  1553. X}
  1554. X
  1555. Xint pty_putgettty(fd,ch,tmo)
  1556. Xint fd;
  1557. Xchar ch;
  1558. Xstruct ttymodes *tmo;
  1559. X{
  1560. X if (bufwrite(fd,&ch,1) < 0)
  1561. X   return -1;
  1562. X if (bufread(fd,(char *) tmo,sizeof(struct ttymodes)) < 0)
  1563. X   return -1;
  1564. X if (bufwrite(fd,".",1) < 0)
  1565. X   return -1;
  1566. X return 0;
  1567. X}
  1568. X
  1569. Xint pty_sendonefd(fd,fp)
  1570. Xint fd;
  1571. Xint *fp;
  1572. X{
  1573. X#ifdef NO_FDPASSING
  1574. X return -1;
  1575. X#else
  1576. X struct msghdr msg[2];
  1577. X int acc[5]; /* or just 5? or just 1? who cares */
  1578. X struct iovec i[2];
  1579. X
  1580. X msg[0].msg_name = 0;
  1581. X msg[0].msg_namelen = 0;
  1582. X msg[0].msg_iov = i; /* grrrr */
  1583. X msg[0].msg_iovlen = 0;
  1584. X msg[0].msg_accrights = (caddr_t) acc;
  1585. X msg[0].msg_accrightslen = sizeof(int);
  1586. X acc[0] = *fp;
  1587. X if (sendmsg(fd,&msg[0],0) == -1)
  1588. X   return -1;
  1589. X /* yay! we've passed a file descriptor! */
  1590. X return 0;
  1591. X#endif
  1592. X}
  1593. X
  1594. Xint pty_sendfd(fd,ch,fp)
  1595. Xint fd;
  1596. Xchar ch;
  1597. Xint *fp;
  1598. X{
  1599. X#ifdef NO_FDPASSING
  1600. X return -1;
  1601. X#else
  1602. X if (bufwrite(fd,&ch,1) < 0)
  1603. X   return -1;
  1604. X if (bufread(fd,&ch,1) < 0)
  1605. X   return -1;
  1606. X if (ch == ' ')
  1607. X   return 1;
  1608. X if (pty_sendonefd(fd,fp) < 0)
  1609. X   return -1;
  1610. X if (bufread(fd,&ch,1) < 0)
  1611. X   return -1;
  1612. X if (ch != '.')
  1613. X   return 1;
  1614. X return 0;
  1615. X#endif
  1616. X}
  1617. X
  1618. Xint pty_sendint(fd,ch,ip)
  1619. Xint fd;
  1620. Xchar ch;
  1621. Xint *ip;
  1622. X{
  1623. X if (bufwrite(fd,&ch,1) < 0)
  1624. X   return -1;
  1625. X if (bufread(fd,&ch,1) < 0)
  1626. X   return -1;
  1627. X if (ch == ' ')
  1628. X   return 1;
  1629. X if (bufwrite(fd,(char *) ip,sizeof(int)) < 0)
  1630. X   return -1;
  1631. X if (bufread(fd,&ch,1) < 0)
  1632. X   return -1;
  1633. X if (ch != '.')
  1634. X   return 1;
  1635. X return 0;
  1636. X}
  1637. X
  1638. Xint pty_sendstr(fd,ch,str)
  1639. Xint fd;
  1640. Xchar ch;
  1641. Xchar str[TTYNAMELEN];
  1642. X{
  1643. X if (bufwrite(fd,&ch,1) < 0)
  1644. X   return -1;
  1645. X if (bufread(fd,&ch,1) < 0)
  1646. X   return -1;
  1647. X if (ch == ' ')
  1648. X   return 1;
  1649. X if (bufwrite(fd,str,TTYNAMELEN) < 0)
  1650. X   return -1;
  1651. X if (bufread(fd,&ch,1) < 0)
  1652. X   return -1;
  1653. X if (ch != '.')
  1654. X   return 1;
  1655. X return 0;
  1656. X}
  1657. X
  1658. Xint pty_sendtty(fd,ch,tmo)
  1659. Xint fd;
  1660. Xchar ch;
  1661. Xstruct ttymodes *tmo;
  1662. X{
  1663. X if (bufwrite(fd,&ch,1) < 0)
  1664. X   return -1;
  1665. X if (bufread(fd,&ch,1) < 0)
  1666. X   return -1;
  1667. X if (ch == ' ')
  1668. X   return 1;
  1669. X if (bufwrite(fd,(char *) tmo,sizeof(struct ttymodes)) < 0)
  1670. X   return -1;
  1671. X if (bufread(fd,&ch,1) < 0)
  1672. X   return -1;
  1673. X if (ch != '.')
  1674. X   return 1;
  1675. X return 0;
  1676. X}
  1677. X
  1678. Xint pty_putch(fd,ch)
  1679. Xint fd;
  1680. Xchar *ch;
  1681. X{
  1682. X return bufwrite(fd,ch,1);
  1683. X}
  1684. X
  1685. Xint pty_getch(fd,ch)
  1686. Xint fd;
  1687. Xchar *ch;
  1688. X{
  1689. X return bufread(fd,ch,1);
  1690. X}
  1691. END_OF_FILE
  1692.   if test 5474 -ne `wc -c <'sock.c'`; then
  1693.     echo shar: \"'sock.c'\" unpacked with wrong size!
  1694.   fi
  1695.   # end of 'sock.c'
  1696. fi
  1697. if test -f 'tty.c' -a "${1}" != "-c" ; then 
  1698.   echo shar: Will not clobber existing file \"'tty.c'\"
  1699. else
  1700.   echo shar: Extracting \"'tty.c'\" \(8009 characters\)
  1701.   sed "s/^X//" >'tty.c' <<'END_OF_FILE'
  1702. X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
  1703. X
  1704. X#include "config.h"
  1705. X#include <sys/ioctl.h>
  1706. X#include "file.h"
  1707. X#include "err.h"
  1708. X#include "tty.h"
  1709. X
  1710. X#define generic GENERIC *
  1711. X
  1712. Xstatic int ioc(fd,req,arg) /* non-interruptable ioctl */
  1713. Xint fd;
  1714. Xunsigned long req;
  1715. Xgeneric arg;
  1716. X{
  1717. X int result;
  1718. X
  1719. X do
  1720. X   result = ioctl(fd,req,(char *) arg);
  1721. X while ((result == -1) && (errno == EINTR));
  1722. X return result;
  1723. X}
  1724. X
  1725. Xint tty_getctrl()
  1726. X{
  1727. X int fd;
  1728. X int dummy;
  1729. X
  1730. X#define ISTTY(f) (ioc(f,(unsigned long) TIOCGPGRP,(generic) &dummy) == 0)
  1731. X
  1732. X if (ISTTY(3))
  1733. X   return 3;
  1734. X if (((fd = open("/dev/tty",O_RDWR)) != -1) && ISTTY(fd))
  1735. X   return fd;
  1736. X if (((fd = dup(0)) != -1) && ISTTY(fd))
  1737. X   return fd;
  1738. X if (((fd = dup(1)) != -1) && ISTTY(fd))
  1739. X   return fd;
  1740. X return -1;
  1741. X}
  1742. X
  1743. Xtty_setexcl(fd)
  1744. Xint fd;
  1745. X{
  1746. X return ioc(fd,(unsigned long) TIOCEXCL,(generic) 0);
  1747. X /* setting exclusive use is a bit unusual but it works */
  1748. X /* opening /dev/tty should still be allowed, though */
  1749. X}
  1750. X
  1751. Xtty_setpgrp(fd,pgrp)
  1752. Xint fd;
  1753. Xint pgrp;
  1754. X{
  1755. X return ioc(fd,(unsigned long) TIOCSPGRP,(generic) &pgrp);
  1756. X}
  1757. X
  1758. Xtty_dissoc(fd)
  1759. Xint fd;
  1760. X{
  1761. X return ioc(fd,(unsigned long) TIOCNOTTY,(generic) 0);
  1762. X}
  1763. X
  1764. Xtty_getmodes(fd,tmo)
  1765. Xint fd;
  1766. Xstruct ttymodes *tmo;
  1767. X{
  1768. X if (ioc(fd,(unsigned long) TIOCGETD,(generic) &(tmo->di)) == -1) return -1;
  1769. X if (ioc(fd,(unsigned long) TIOCGETP,(generic) &(tmo->sg)) == -1) return -1;
  1770. X if (ioc(fd,(unsigned long) TIOCGETC,(generic) &(tmo->tc)) == -1) return -1;
  1771. X if (ioc(fd,(unsigned long) TIOCLGET,(generic) &(tmo->lb)) == -1) return -1;
  1772. X if (ioc(fd,(unsigned long) TIOCGLTC,(generic) &(tmo->lt)) == -1) return -1;
  1773. X#ifdef TTY_WINDOWS
  1774. X if (ioc(fd,(unsigned long) TIOCGWINSZ,(generic) &(tmo->ws)) == -1) return -1;
  1775. X#endif
  1776. X#ifdef TTY_AUXCHARS
  1777. X if (ioc(fd,(unsigned long) TIOCGAUXC,(generic) &(tmo->au)) == -1) return -1;
  1778. X#endif
  1779. X return 0;
  1780. X}
  1781. X
  1782. Xtty_setmodes(fd,tmo)
  1783. Xint fd;
  1784. Xstruct ttymodes *tmo;
  1785. X{
  1786. X if (ioc(fd,(unsigned long) TIOCSETD,(generic) &(tmo->di)) == -1) return -1;
  1787. X if (ioc(fd,(unsigned long) TIOCSETP,(generic) &(tmo->sg)) == -1) return -1;
  1788. X if (ioc(fd,(unsigned long) TIOCSETC,(generic) &(tmo->tc)) == -1) return -1;
  1789. X if (ioc(fd,(unsigned long) TIOCLSET,(generic) &(tmo->lb)) == -1) return -1;
  1790. X if (ioc(fd,(unsigned long) TIOCSLTC,(generic) &(tmo->lt)) == -1) return -1;
  1791. X#ifdef TTY_WINDOWS
  1792. X if (ioc(fd,(unsigned long) TIOCSWINSZ,(generic) &(tmo->ws)) == -1) return -1;
  1793. X#endif
  1794. X#ifdef TTY_AUXCHARS
  1795. X if (ioc(fd,(unsigned long) TIOCSAUXC,(generic) &(tmo->au)) == -1) return -1;
  1796. X#endif
  1797. X return 0;
  1798. X}
  1799. X
  1800. Xtty_modifymodes(fd,tmonew,tmoold)
  1801. Xint fd;
  1802. Xstruct ttymodes *tmonew;
  1803. Xstruct ttymodes *tmoold;
  1804. X{
  1805. X if (tmonew->di != tmoold->di)
  1806. X   if (ioc(fd,(unsigned long) TIOCSETD,(generic) &(tmonew->di)) == -1) return -1;
  1807. X if ((tmonew->sg.sg_flags != tmoold->sg.sg_flags)
  1808. X   ||(tmonew->sg.sg_ispeed != tmoold->sg.sg_ispeed)
  1809. X   ||(tmonew->sg.sg_ospeed != tmoold->sg.sg_ospeed)
  1810. X   ||(tmonew->sg.sg_erase != tmoold->sg.sg_erase)
  1811. X   ||(tmonew->sg.sg_kill != tmoold->sg.sg_kill))
  1812. X   if (ioc(fd,(unsigned long) TIOCSETP,(generic) &(tmonew->sg)) == -1) return -1;
  1813. X if ((tmonew->tc.t_intrc != tmoold->tc.t_intrc)
  1814. X   ||(tmonew->tc.t_quitc != tmoold->tc.t_quitc)
  1815. X   ||(tmonew->tc.t_startc != tmoold->tc.t_startc)
  1816. X   ||(tmonew->tc.t_stopc != tmoold->tc.t_stopc)
  1817. X   ||(tmonew->tc.t_eofc != tmoold->tc.t_eofc)
  1818. X   ||(tmonew->tc.t_brkc != tmoold->tc.t_brkc))
  1819. X   if (ioc(fd,(unsigned long) TIOCSETC,(generic) &(tmonew->tc)) == -1) return -1;
  1820. X if (tmonew->lb != tmoold->lb)
  1821. X   if (ioc(fd,(unsigned long) TIOCLSET,(generic) &(tmonew->lb)) == -1) return -1;
  1822. X if ((tmonew->lt.t_suspc != tmoold->lt.t_suspc)
  1823. X   ||(tmonew->lt.t_dsuspc != tmoold->lt.t_dsuspc)
  1824. X   ||(tmonew->lt.t_rprntc != tmoold->lt.t_rprntc)
  1825. X   ||(tmonew->lt.t_flushc != tmoold->lt.t_flushc)
  1826. X   ||(tmonew->lt.t_werasc != tmoold->lt.t_werasc)
  1827. X   ||(tmonew->lt.t_lnextc != tmoold->lt.t_lnextc))
  1828. X   if (ioc(fd,(unsigned long) TIOCSLTC,(generic) &(tmonew->lt)) == -1) return -1;
  1829. X#ifdef TTY_WINDOWS
  1830. X if ((tmonew->ws.ws_xpixel != tmoold->ws.ws_xpixel)
  1831. X   ||(tmonew->ws.ws_ypixel != tmoold->ws.ws_ypixel)
  1832. X   ||(tmonew->ws.ws_row != tmoold->ws.ws_row)
  1833. X   ||(tmonew->ws.ws_col != tmoold->ws.ws_col))
  1834. X   if (ioc(fd,(unsigned long)TIOCSWINSZ,(generic)&(tmonew->ws))==-1) return -1;
  1835. X#endif
  1836. X#ifdef TTY_AUXCHARS
  1837. X if ((tmonew->au.t_usemap != tmoold->au.t_usemap)
  1838. X   ||(tmonew->au.t_usest != tmoold->au.t_usest))
  1839. X   if (ioc(fd,(unsigned long)TIOCSAUXC,(generic)&(tmonew->au))==-1) return -1;
  1840. X#endif
  1841. X return 0;
  1842. X}
  1843. X
  1844. X/* XXX: Should use copy() for this. */
  1845. Xvoid tty_copymodes(tmonew,tmoold)
  1846. Xstruct ttymodes *tmonew;
  1847. Xstruct ttymodes *tmoold;
  1848. X{
  1849. X tmonew->di = tmoold->di;
  1850. X tmonew->sg.sg_ispeed = tmoold->sg.sg_ispeed;
  1851. X tmonew->sg.sg_ospeed = tmoold->sg.sg_ospeed;
  1852. X tmonew->sg.sg_erase = tmoold->sg.sg_erase;
  1853. X tmonew->sg.sg_kill = tmoold->sg.sg_kill;
  1854. X tmonew->sg.sg_flags = tmoold->sg.sg_flags;
  1855. X tmonew->tc.t_intrc = tmoold->tc.t_intrc;
  1856. X tmonew->tc.t_quitc = tmoold->tc.t_quitc;
  1857. X tmonew->tc.t_startc = tmoold->tc.t_startc;
  1858. X tmonew->tc.t_stopc = tmoold->tc.t_stopc;
  1859. X tmonew->tc.t_eofc = tmoold->tc.t_eofc;
  1860. X tmonew->tc.t_brkc = tmoold->tc.t_brkc;
  1861. X tmonew->lb = tmoold->lb;
  1862. X tmonew->lt.t_suspc = tmoold->lt.t_suspc;
  1863. X tmonew->lt.t_dsuspc = tmoold->lt.t_dsuspc;
  1864. X tmonew->lt.t_rprntc = tmoold->lt.t_rprntc;
  1865. X tmonew->lt.t_flushc = tmoold->lt.t_flushc;
  1866. X tmonew->lt.t_werasc = tmoold->lt.t_werasc;
  1867. X tmonew->lt.t_lnextc = tmoold->lt.t_lnextc;
  1868. X#ifdef TTY_WINDOWS
  1869. X tmonew->ws.ws_xpixel = tmoold->ws.ws_xpixel;
  1870. X tmonew->ws.ws_ypixel = tmoold->ws.ws_ypixel;
  1871. X tmonew->ws.ws_row = tmoold->ws.ws_row;
  1872. X tmonew->ws.ws_col = tmoold->ws.ws_col;
  1873. X#endif
  1874. X#ifdef TTY_AUXCHARS
  1875. X tmonew->au.t_usest = tmoold->au.t_usest;
  1876. X tmonew->au.t_usemap = tmoold->au.t_usemap;
  1877. X#endif
  1878. X}
  1879. X
  1880. Xvoid tty_copywin(tmonew,tmoold)
  1881. Xstruct ttymodes *tmonew;
  1882. Xstruct ttymodes *tmoold;
  1883. X{
  1884. X ;
  1885. X#ifdef TTY_WINDOWS
  1886. X tmonew->ws.ws_xpixel = tmoold->ws.ws_xpixel;
  1887. X tmonew->ws.ws_ypixel = tmoold->ws.ws_ypixel;
  1888. X tmonew->ws.ws_row = tmoold->ws.ws_row;
  1889. X tmonew->ws.ws_col = tmoold->ws.ws_col;
  1890. X#endif
  1891. X}
  1892. X
  1893. Xvoid tty_charmode(tmo)
  1894. Xstruct ttymodes *tmo;
  1895. X{
  1896. X tty_mungemodes(tmo,3,0,2,0,3,0);
  1897. X}
  1898. X
  1899. Xvoid tty_mungemodes(tmo,cbreak,new,echo,crmod,raw,crt)
  1900. Xstruct ttymodes *tmo;
  1901. Xint cbreak;
  1902. Xint new;
  1903. Xint echo;
  1904. Xint crmod;
  1905. Xint raw;
  1906. Xint crt;
  1907. X{
  1908. X if (new >= 2)
  1909. X   tmo->di = ((new == 3) ? NTTYDISC : OTTYDISC);
  1910. X if (crmod >= 2)
  1911. X   tmo->sg.sg_flags = (tmo->sg.sg_flags & ~CRMOD) | (CRMOD * (crmod == 3));
  1912. X if (echo >= 2)
  1913. X   tmo->sg.sg_flags = (tmo->sg.sg_flags & ~ECHO) | (ECHO * (echo == 3));
  1914. X if (raw >= 2)
  1915. X   tmo->sg.sg_flags = (tmo->sg.sg_flags & ~RAW) | (RAW * (raw == 3));
  1916. X if (cbreak >= 2)
  1917. X   tmo->sg.sg_flags = (tmo->sg.sg_flags & ~CBREAK) | (CBREAK * (cbreak == 3));
  1918. X if (crt >= 2)
  1919. X   tmo->lb = (tmo->lb & ~(CRTBS | CRTERA | CRTKIL | CTLECH))
  1920. X                      | ((CRTBS | CRTERA | CRTKIL | CTLECH) * (crt == 3));
  1921. X}
  1922. X
  1923. Xvoid tty_initmodes(tmo,cbreak,new,echo,crmod,raw,crt)
  1924. Xstruct ttymodes *tmo;
  1925. Xint cbreak;
  1926. Xint new;
  1927. Xint echo;
  1928. Xint crmod;
  1929. Xint raw;
  1930. Xint crt;
  1931. X{
  1932. X /* Here we specify Ye Standard BSD Terminal Settings. */
  1933. X
  1934. X tmo->di = ((new % 2) ? NTTYDISC : OTTYDISC);
  1935. X tmo->sg.sg_ispeed = EXTB;
  1936. X tmo->sg.sg_ospeed = EXTB;
  1937. X tmo->sg.sg_erase = 127; /* del */
  1938. X tmo->sg.sg_kill = 21; /* ^U */
  1939. X tmo->sg.sg_flags = EVENP | ODDP | XTABS
  1940. X   | (CRMOD * (crmod % 2)) | (ECHO * (echo % 2))
  1941. X   | (RAW * (raw % 2)) | (CBREAK * (cbreak % 2));
  1942. X tmo->tc.t_intrc = 3; /* ^C */
  1943. X tmo->tc.t_quitc = 28; /* ^\ */
  1944. X tmo->tc.t_startc = 17; /* ^Q */
  1945. X tmo->tc.t_stopc = 19; /* ^S */
  1946. X tmo->tc.t_eofc = 4; /* ^D */
  1947. X tmo->tc.t_brkc = -1; /* undef */
  1948. X tmo->lb = ((CRTBS | CRTERA | CRTKIL | CTLECH) * (crt % 2)) | DECCTQ;
  1949. X tmo->lt.t_suspc = 26; /* ^Z */
  1950. X tmo->lt.t_dsuspc = 25; /* ^Y */
  1951. X tmo->lt.t_rprntc = 18; /* ^R */
  1952. X tmo->lt.t_flushc = 15; /* ^O */
  1953. X tmo->lt.t_werasc = 23; /* ^W */
  1954. X tmo->lt.t_lnextc = 22; /* ^V */
  1955. X#ifdef TTY_WINDOWS
  1956. X tmo->ws.ws_xpixel = 0; /* Or read from TERMCAP? Hmmm */
  1957. X tmo->ws.ws_ypixel = 0;
  1958. X tmo->ws.ws_row = 0;
  1959. X tmo->ws.ws_col = 0;
  1960. X#endif
  1961. X#ifdef TTY_AUXCHARS
  1962. X tmo->au.t_usest = 20; /* ^T */
  1963. X tmo->au.t_usemap = UST_LOAD1 | UST_LOAD5 | UST_LOAD15 | UST_RAWCPU
  1964. X   | UST_UPTIME | UST_PGRP | UST_CHILDS | UST_PCPU | UST_STATE;
  1965. X#endif
  1966. X}
  1967. END_OF_FILE
  1968.   if test 8009 -ne `wc -c <'tty.c'`; then
  1969.     echo shar: \"'tty.c'\" unpacked with wrong size!
  1970.   fi
  1971.   # end of 'tty.c'
  1972. fi
  1973. if test -f 'util/Makefile' -a "${1}" != "-c" ; then 
  1974.   echo shar: Will not clobber existing file \"'util/Makefile'\"
  1975. else
  1976.   echo shar: Extracting \"'util/Makefile'\" \(4818 characters\)
  1977.   sed "s/^X//" >'util/Makefile' <<'END_OF_FILE'
  1978. XCC=cc
  1979. XCCOPTS=-O2 -s
  1980. X
  1981. XNROFF=nroff
  1982. XNROFFOPTS=-man
  1983. X
  1984. X# This Makefile is exceedingly boring. Then again, it's portable.
  1985. X
  1986. Xdefault: all
  1987. X
  1988. Xall: progs mans
  1989. X
  1990. Xprogs: excloff exclon lock tiocsti who u biff mesg tty write wall sessuser sessname sesskill sesslist disconnect reconnect xsessuser xsessname xsesskill xsesslist xdisconnect xreconnect sessutil.o xsessutil.o
  1991. X
  1992. Xmans: excloff.man exclon.man lock.man tiocsti.man who.man u.man biff.man mesg.man tty.man write.man wall.man sessuser.man sessname.man sesskill.man sesslist.man disconnect.man reconnect.man script.man script.tidy.man condom.man sess.man
  1993. X
  1994. Xexcloff: excloff.c Makefile
  1995. X    $(CC) $(CCOPTS) -o excloff excloff.c
  1996. X
  1997. Xexclon: exclon.c Makefile
  1998. X    $(CC) $(CCOPTS) -o exclon exclon.c
  1999. X
  2000. Xlock: lock.c Makefile
  2001. X    $(CC) $(CCOPTS) -o lock lock.c -lcurses -ltermcap
  2002. X
  2003. Xtiocsti: tiocsti.c Makefile
  2004. X    $(CC) $(CCOPTS) -o tiocsti tiocsti.c
  2005. X
  2006. Xwho: who.c Makefile
  2007. X    $(CC) $(CCOPTS) -o who who.c
  2008. X
  2009. Xu: u.c Makefile
  2010. X    $(CC) $(CCOPTS) -o u u.c
  2011. X
  2012. Xtty: tty.c Makefile
  2013. X    $(CC) $(CCOPTS) -o tty tty.c
  2014. X
  2015. Xwrite: write.c Makefile
  2016. X    $(CC) $(CCOPTS) -o write write.c
  2017. X
  2018. Xwall: wall.c Makefile
  2019. X    $(CC) $(CCOPTS) -o wall wall.c
  2020. X
  2021. Xbiff: biff.o sessutil.o Makefile
  2022. X    $(CC) $(CCOPTS) -o biff biff.o sessutil.o
  2023. X
  2024. Xmesg: mesg.o sessutil.o Makefile
  2025. X    $(CC) $(CCOPTS) -o mesg mesg.o sessutil.o
  2026. X
  2027. Xsessuser: sessuser.o sessutil.o Makefile
  2028. X    $(CC) $(CCOPTS) -o sessuser sessuser.o sessutil.o
  2029. X
  2030. Xxsessuser: sessuser.o xsessutil.o Makefile
  2031. X    $(CC) $(CCOPTS) -o xsessuser sessuser.o xsessutil.o
  2032. X
  2033. Xsessname: sessname.o sessutil.o Makefile
  2034. X    $(CC) $(CCOPTS) -o sessname sessname.o sessutil.o
  2035. X
  2036. Xxsessname: sessname.o xsessutil.o Makefile
  2037. X    $(CC) $(CCOPTS) -o xsessname sessname.o xsessutil.o
  2038. X
  2039. Xsesskill: sesskill.o sessutil.o Makefile
  2040. X    $(CC) $(CCOPTS) -o sesskill sesskill.o sessutil.o
  2041. X
  2042. Xxsesskill: sesskill.o xsessutil.o Makefile
  2043. X    $(CC) $(CCOPTS) -o xsesskill sesskill.o xsessutil.o
  2044. X
  2045. Xsesslist: sesslist.o sessutil.o Makefile
  2046. X    $(CC) $(CCOPTS) -o sesslist sesslist.o sessutil.o
  2047. X
  2048. Xxsesslist: sesslist.o xsessutil.o Makefile
  2049. X    $(CC) $(CCOPTS) -o xsesslist sesslist.o xsessutil.o
  2050. X
  2051. Xreconnect: reconnect.o sessutil.o Makefile
  2052. X    $(CC) $(CCOPTS) -o reconnect reconnect.o sessutil.o
  2053. X
  2054. Xxreconnect: reconnect.o xsessutil.o Makefile
  2055. X    $(CC) $(CCOPTS) -o xreconnect reconnect.o xsessutil.o
  2056. X
  2057. Xdisconnect: disconnect.o sessutil.o Makefile
  2058. X    $(CC) $(CCOPTS) -o disconnect disconnect.o sessutil.o
  2059. X
  2060. Xxdisconnect: disconnect.o xsessutil.o Makefile
  2061. X    $(CC) $(CCOPTS) -o xdisconnect disconnect.o xsessutil.o
  2062. X
  2063. Xbiff.o: biff.c sessutil.h Makefile
  2064. X    $(CC) $(CCOPTS) -c biff.c
  2065. X
  2066. Xmesg.o: mesg.c sessutil.h Makefile
  2067. X    $(CC) $(CCOPTS) -c mesg.c
  2068. X
  2069. Xsessuser.o: sessuser.c sessutil.h Makefile
  2070. X    $(CC) $(CCOPTS) -c sessuser.c
  2071. X
  2072. Xsessname.o: sessname.c sessutil.h Makefile
  2073. X    $(CC) $(CCOPTS) -c sessname.c
  2074. X
  2075. Xsesskill.o: sesskill.c sessutil.h Makefile
  2076. X    $(CC) $(CCOPTS) -c sesskill.c
  2077. X
  2078. Xsesslist.o: sesslist.c sessutil.h Makefile
  2079. X    $(CC) $(CCOPTS) -c sesslist.c
  2080. X
  2081. Xdisconnect.o: disconnect.c sessutil.h Makefile
  2082. X    $(CC) $(CCOPTS) -c disconnect.c
  2083. X
  2084. Xreconnect.o: reconnect.c sessutil.h Makefile
  2085. X    $(CC) $(CCOPTS) -c reconnect.c
  2086. X
  2087. Xxsessutil.o: xsessutil.c sessutil.h Makefile
  2088. X    $(CC) $(CCOPTS) -c xsessutil.c
  2089. X
  2090. Xsessutil.o: sessutil.c sessutil.h Makefile
  2091. X    $(CC) $(CCOPTS) -c sessutil.c
  2092. X
  2093. Xexcloff.man: excloff.1 Makefile
  2094. X    $(NROFF) $(NROFFOPTS) < excloff.1 > excloff.man
  2095. X
  2096. Xexclon.man: exclon.1 Makefile
  2097. X    $(NROFF) $(NROFFOPTS) < exclon.1 > exclon.man
  2098. X
  2099. Xlock.man: lock.1 Makefile
  2100. X    $(NROFF) $(NROFFOPTS) < lock.1 > lock.man
  2101. X
  2102. Xtiocsti.man: tiocsti.1 Makefile
  2103. X    $(NROFF) $(NROFFOPTS) < tiocsti.1 > tiocsti.man
  2104. X
  2105. Xwho.man: who.1 Makefile
  2106. X    $(NROFF) $(NROFFOPTS) < who.1 > who.man
  2107. X
  2108. Xbiff.man: biff.1 Makefile
  2109. X    $(NROFF) $(NROFFOPTS) < biff.1 > biff.man
  2110. X
  2111. Xmesg.man: mesg.1 Makefile
  2112. X    $(NROFF) $(NROFFOPTS) < mesg.1 > mesg.man
  2113. X
  2114. Xu.man: u.1 Makefile
  2115. X    $(NROFF) $(NROFFOPTS) < u.1 > u.man
  2116. X
  2117. Xtty.man: tty.1 Makefile
  2118. X    $(NROFF) $(NROFFOPTS) < tty.1 > tty.man
  2119. X
  2120. Xwrite.man: write.1 Makefile
  2121. X    $(NROFF) $(NROFFOPTS) < write.1 > write.man
  2122. X
  2123. Xwall.man: wall.1 Makefile
  2124. X    $(NROFF) $(NROFFOPTS) < wall.1 > wall.man
  2125. X
  2126. Xsess.man: sess.1 Makefile
  2127. X    $(NROFF) $(NROFFOPTS) < sess.1 > sess.man
  2128. X
  2129. Xsessuser.man: sessuser.1 Makefile
  2130. X    $(NROFF) $(NROFFOPTS) < sessuser.1 > sessuser.man
  2131. X
  2132. Xsessname.man: sessname.1 Makefile
  2133. X    $(NROFF) $(NROFFOPTS) < sessname.1 > sessname.man
  2134. X
  2135. Xsesskill.man: sesskill.1 Makefile
  2136. X    $(NROFF) $(NROFFOPTS) < sesskill.1 > sesskill.man
  2137. X
  2138. Xsesslist.man: sesslist.1 Makefile
  2139. X    $(NROFF) $(NROFFOPTS) < sesslist.1 > sesslist.man
  2140. X
  2141. Xcondom.man: condom.1 Makefile
  2142. X    $(NROFF) $(NROFFOPTS) < condom.1 > condom.man
  2143. X
  2144. Xscript.man: script.1 Makefile
  2145. X    $(NROFF) $(NROFFOPTS) < script.1 > script.man
  2146. X
  2147. Xscript.tidy.man: script.tidy.1 Makefile
  2148. X    $(NROFF) $(NROFFOPTS) < script.tidy.1 > script.tidy.man
  2149. X
  2150. Xreconnect.man: reconnect.1 Makefile
  2151. X    $(NROFF) $(NROFFOPTS) < reconnect.1 > reconnect.man
  2152. X
  2153. Xdisconnect.man: disconnect.1 Makefile
  2154. X    $(NROFF) $(NROFFOPTS) < disconnect.1 > disconnect.man
  2155. END_OF_FILE
  2156.   if test 4818 -ne `wc -c <'util/Makefile'`; then
  2157.     echo shar: \"'util/Makefile'\" unpacked with wrong size!
  2158.   fi
  2159.   # end of 'util/Makefile'
  2160. fi
  2161. echo shar: End of archive 3 \(of 6\).
  2162. cp /dev/null ark3isdone
  2163. MISSING=""
  2164. for I in 1 2 3 4 5 6 ; do
  2165.     if test ! -f ark${I}isdone ; then
  2166.     MISSING="${MISSING} ${I}"
  2167.     fi
  2168. done
  2169. if test "${MISSING}" = "" ; then
  2170.     echo You have unpacked all 6 archives.
  2171.     rm -f ark[1-9]isdone
  2172. else
  2173.     echo You still must unpack the following archives:
  2174.     echo "        " ${MISSING}
  2175. fi
  2176. exit 0
  2177. exit 0 # Just in case...
  2178. -- 
  2179. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  2180. Use a domain-based address or give alternate paths, or you may lose out.
  2181.